package cc.rengu.redp.bizimpl.upmp.service.impl;

import cc.rengu.redp.bizimpl.constant.UpmpConstant;
import cc.rengu.redp.bizimpl.upmp.domain.UpmpMenu;
import cc.rengu.redp.bizimpl.upmp.domain.UpmpRole;
import cc.rengu.redp.bizimpl.upmp.domain.UpmpUserInfo;
import cc.rengu.redp.bizimpl.upmp.service.IUpmpCacheService;
import cc.rengu.redp.bizimpl.upmp.service.IUpmpMenuService;
import cc.rengu.redp.bizimpl.upmp.service.IUpmpRoleService;
import cc.rengu.redp.bizimpl.upmp.service.IUpmpUserInfoService;
import cc.rengu.redp.bizimpl.upmp.vo.UpmpUserInfoVO;
import cc.rengu.redp.common.redis.RedisService;
import cc.rengu.redp.system.domain.UserConfig;
import cc.rengu.redp.system.service.UserConfigService;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.List;
import java.util.stream.Collectors;

@Service("upmpCacheService")
public class UpmpCacheServiceImpl implements IUpmpCacheService {

    @Autowired
    private RedisService redisService;

    @Autowired
    private IUpmpRoleService UpmpRoleService;

    @Autowired
    private IUpmpMenuService UpmpMenuService;

    @Autowired
    private IUpmpUserInfoService UpmpUserInfoService;

    @Autowired
    private UserConfigService userConfigService;

    @Autowired
    private ObjectMapper mapper;

    @Override
    public void testConnect() throws Exception {
        this.redisService.exists("test");
    }

    @Override
    public UpmpUserInfoVO getUser(String userId) throws Exception {
        String userString = this.redisService.get(UpmpConstant.USER_CACHE_PREFIX + userId);
        if (StringUtils.isBlank(userString)) {
            throw new Exception();
        } else {
            return this.mapper.readValue(userString, UpmpUserInfoVO.class);
        }
    }

    @Override
    public UpmpUserInfo getUser(String instId,String loginId) throws Exception {
        String userString = this.redisService.get(UpmpConstant.USER_CACHE_PREFIX+ instId + loginId);
        if (StringUtils.isBlank(userString)) {
            throw new Exception();
        } else {
            return this.mapper.readValue(userString, UpmpUserInfo.class);
        }
    }

    @Override
    public List<UpmpRole> getRoles(String userId) throws Exception {
        String roleListString = this.redisService.get(UpmpConstant.USER_ROLE_CACHE_PREFIX + userId);
        if (StringUtils.isBlank(roleListString)) {
            throw new Exception();
        } else {
            JavaType type = mapper.getTypeFactory().constructParametricType(List.class, UpmpRole.class);
            return this.mapper.readValue(roleListString, type);
        }
    }

    @Override
    public List<UpmpMenu> getPermissions(String userId) throws Exception {
        String permissionListString = this.redisService.get(UpmpConstant.USER_PERMISSION_CACHE_PREFIX + userId);
        if (StringUtils.isBlank(permissionListString)) {
            throw new Exception();
        } else {
            JavaType type = mapper.getTypeFactory().constructParametricType(List.class, UpmpMenu.class);
            return this.mapper.readValue(permissionListString, type);
        }
    }

    @Override
    public UserConfig getUserConfig(String userId) throws Exception {
        String userConfigString = this.redisService.get(UpmpConstant.USER_CONFIG_CACHE_PREFIX + userId);
        if (StringUtils.isBlank(userConfigString)) {
            throw new Exception();
        } else {
            return this.mapper.readValue(userConfigString, UserConfig.class);
        }
    }

    @Override
    public void saveUser(UpmpUserInfoVO user) throws Exception {
        String userId = user.getId();
        this.deleteUser(userId);
        redisService.set(UpmpConstant.USER_CACHE_PREFIX + userId, mapper.writeValueAsString(user));
    }

    @Override
    public void saveUser(String userId) throws Exception {
        UpmpUserInfoVO user = UpmpUserInfoService.findDetail(userId);
        this.deleteUser(userId);
        redisService.set(UpmpConstant.USER_CACHE_PREFIX + userId, mapper.writeValueAsString(user));
    }

    @Override
    public void saveRoles(String userId) throws Exception {
        List<UpmpRole> roleList = this.UpmpRoleService.findUserRole(userId);
        if (!roleList.isEmpty()) {
            this.deleteRoles(userId);
            redisService.set(UpmpConstant.USER_ROLE_CACHE_PREFIX + userId, mapper.writeValueAsString(roleList));
        }

    }

    @Override
    public void savePermissions(String userId) throws Exception {
        List<UpmpRole> roles=this.getRoles(userId);
        int superAdmin = roles.stream().filter(role-> UpmpConstant.SYS_ROLE_SUPER_USER_ROLE_PARAM.equals(role.getRoleCode())).collect(Collectors.toList()).size();
        List<UpmpMenu> permissionList;
        if(superAdmin>0){//超管角色可以获取所有权限
            permissionList = this.UpmpMenuService.list().stream()
                    .filter(menu-> !ObjectUtils.isEmpty(menu.getPerms())).collect(Collectors.toList());
        }else{
            permissionList = this.UpmpMenuService.findUserPermissions(userId);
        }
        if (!permissionList.isEmpty()) {
            this.deletePermissions(userId);
            redisService.set(UpmpConstant.USER_PERMISSION_CACHE_PREFIX + userId, mapper.writeValueAsString(permissionList));
        }
    }

    @Override
    public void saveUserConfigs(String userId) throws Exception {
        UserConfig userConfig = this.userConfigService.findByUserId(userId);
        if (userConfig != null) {
            this.deleteUserConfigs(userId);
            redisService.set(UpmpConstant.USER_CONFIG_CACHE_PREFIX + userId, mapper.writeValueAsString(userConfig));
        }
    }

    @Override
    public void deleteUser(String userId) throws Exception {
        userId = userId.toLowerCase();
        redisService.del(UpmpConstant.USER_CACHE_PREFIX + userId);
    }

    @Override
    public void deleteRoles(String userId) throws Exception {
        userId = userId.toLowerCase();
        redisService.del(UpmpConstant.USER_ROLE_CACHE_PREFIX + userId);
    }

    @Override
    public void deletePermissions(String userId) throws Exception {
        userId = userId.toLowerCase();
        redisService.del(UpmpConstant.USER_PERMISSION_CACHE_PREFIX + userId);
    }

    @Override
    public void deleteUserConfigs(String userId) throws Exception {
        redisService.del(UpmpConstant.USER_CONFIG_CACHE_PREFIX + userId);
    }
}
